package com.happysunrise.nru.managers.imp;

import com.alibaba.druid.support.logging.Log;
import com.github.pagehelper.PageHelper;
import com.happysunrise.nru.daos.*;
import com.happysunrise.nru.enumerations.*;
import com.happysunrise.nru.managers.ITeamManager;
import com.happysunrise.nru.models.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 团队管理.
 * <p>
 * Created by liukaixin on 16/9/6.
 */
@Component
public class TeamManager implements ITeamManager {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(TeamManager.class);

    @Autowired
    private ITeamDao teamDao;
    @Autowired
    private IApplyDao applyDao;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private ITeamMemberDao teamMemberDao;

    /**
     * 获取发布状态的团队.
     *
     * @param page 页码
     * @param rows 条数
     * @return 团队列表
     */
    @Override
    public List<Team> getReleasedTeams(Integer page, Integer rows) {
        PageHelper.startPage(page, rows);
        PageHelper.orderBy(QueryOrderEnum.CREATE_TIME.getOrder());
        try {
            return teamDao.getTeamsByStatus(TeamStatusEnum.RELEASE.getStatus());
        } catch (RuntimeException e) {
            LOGGER.error("获取团队列表异常:", e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据团队id获取团队详情.
     *
     * @param id 团队id
     * @return 团队实体
     */
    @Override
    public Team getTeamDescById(Integer id) {
        try {
            return teamDao.getTeamDescById(id);
        } catch (RuntimeException e) {
            LOGGER.error("根据id获取竞赛详情异常:", e);
            return null;
        }
    }

    @Override
    public Team getTeamNameAndCompetitionNameById(Integer id) {
        try {
            return teamDao.getTeamNameAndCompetitionNameById(id);
        } catch (RuntimeException e) {
            LOGGER.error("根据id获取团队名称和竞赛名称异常", e);
            return null;
        }
    }

    /**
     * 添加加入团队申请.
     *
     * @param apply 申请
     */
    @Override
    public void addJoinTeamApply(Apply apply) {
        applyDao.addJoinTeamApply(apply);
    }

    /**
     * 创建团队
     *
     * @param team 团队
     */
    @Override
    public void createTeam(Team team) {
        teamDao.createTeam(team);
    }


    /**
     * 根据竞赛id获取团队列表.
     *
     * @param page          页码
     * @param rows          条数
     * @param competitionId 竞赛id
     * @return 团队列表
     */
    @Override
    public List<Team> getTeamsByCompetitionId(Integer page, Integer rows, Integer competitionId) {
        PageHelper.startPage(page, rows);
        PageHelper.orderBy(QueryOrderEnum.CREATE_TIME.getOrder());
        try {
            return teamDao.getTeamsByCompetitionId(competitionId);
        } catch (RuntimeException e) {
            LOGGER.error("根据竞赛id获取团队列表异常:", e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据团队id和申请人id判断是否已申请加入过团队.
     *
     * @param teamId 团队id
     * @param userId 申请人id
     * @return
     */
    @Override
    public Integer getApplyStatus(Integer teamId, Integer userId) {
        try {
            Integer status = applyDao.getApplyStatusByTeamIdAndApplyUserId(teamId, userId);
            if (status == null || status == 0) {
                return -1;
            } else {
                return status;
            }
        } catch (RuntimeException e) {
            LOGGER.error("获取是否申请加入过团队异常:", e);
            return -1;
        }
    }

    /**
     * 根据申请id获取申请.
     *
     * @param id 申请id
     * @return
     */
    @Override
    public Apply getApplyById(Integer id) {
        try {
            Apply apply = applyDao.getApplyById(id);
            User user = userDao.getUserById(apply.getApplyUserId());
            apply.setApplyUserDegree(user.getDegree());
            apply.setApplyUserRealName(user.getRealName());
            apply.setApplyUserSchool(user.getSchool());
            apply.setApplyUserPic(user.getPic());
            apply.setApplyUserNickName(user.getNickName());
            return apply;
        } catch (RuntimeException e) {
            LOGGER.error("根据id获取申请异常, id = [{}]", id, e);
            return null;
        }
    }

    /**
     * 根据申请id更改状态.
     *
     * @param applyId 申请id
     * @param status  要更改的状态
     * @return
     */
    @Override
    public Integer updateApplyStatus(Integer applyId, Integer status) {
        try {
            applyDao.updateApplyStatus(applyId, status);
            return ResultTypeEnum.SUCCESS.getValue();
        } catch (RuntimeException e) {
            LOGGER.error("更新[{}]状态为[{}]异常", applyId, status, e);
            return ResultTypeEnum.FAILED.getValue();
        }
    }

    /**
     * 获取申请人同比赛其他团队的申请状态.
     *
     * @param applyUserId     申请人id
     * @param competitionName 比赛名称
     * @return 申请状态
     */
    @Override
    public Set<Integer> getOtherApplyStatus(Integer applyUserId, String competitionName) {
        try {
            return applyDao.getOtherApplyStatus(applyUserId, competitionName);
        } catch (RuntimeException e) {
            LOGGER.error("获取其他团队申请状态异常:", e);
            return new HashSet<>();
        }
    }

    @Override
    public Integer addTeamMember(TeamMember teamMember) {
        return teamMemberDao.addTeamMember(teamMember);
    }

    @Override
    public Integer getTeamIdByName(String name) {
        return teamDao.getTeamIdByName(name);
    }

    /**
     * 获取我的申请列表.
     *
     * @param page   页码
     * @param rows   条数
     * @param userId 用户id
     * @return
     */
    @Override
    public List<Apply> getMyAppliesByUserId(Integer page, Integer rows, Integer userId) {
        try {
            PageHelper.startPage(page, rows);
            PageHelper.orderBy(QueryOrderEnum.CREATE_TIME.getOrder());
            return applyDao.getMyAppliesByUserId(userId);
        } catch (RuntimeException e) {
            LOGGER.error("获取我的申请列表异常, 页码为[{}], 条数为[{}], 用户id为[{}]", page, rows, userId, e);
            return new ArrayList<>();
        }
    }

    @Override
    public Integer getTeamIdByUserIdAndCompId(Integer userId, Integer competitionId) {
        return teamDao.getTeamIdByUserIdAndCompId(userId, competitionId);
    }

    /**
     * 根据userId获取我要审核的团队申请.
     *
     * @param page   页码
     * @param rows   条数
     * @param userId 用户id（team_creator_id)
     * @return
     */
    @Override
    public List<Notice> getMyChecksByUserId(Integer page, Integer rows, Integer userId) {
        try {
            PageHelper.startPage(page, rows);
            PageHelper.orderBy(QueryOrderEnum.CREATE_TIME.getOrder());
            List<Apply> checks = applyDao.getMyChecksByUserId(userId);
            List<Notice> notices = new ArrayList<>();
            for (Apply apply : checks) {
                Notice notice = new Notice();
                notice.setCategory(NoticeTypeEnum.TEAM_NOTICE.getTypeCode());
                notice.setCreateTime(apply.getCreateTime());
                notice.setIdForCategory(apply.getId());
                notice.setTitle("您的团队[" + apply.getTeamName() + "]收到一条加入申请");
                notice.setInfo("参加竞赛：" + apply.getCompetitionName());
                notice.setUserId(userId);
                notice.setRead(apply.getStatus());
                notices.add(notice);
            }
            return notices;
        } catch (RuntimeException e) {
            LOGGER.error("获取我我要审核的团队申请列表异常, " +
                    "页码为[{}], 条数为[{}], 用户id为[{}]", page, rows, userId, e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<TeamMember> getTeamMembers(Integer teamId) {
        try {
            return teamDao.getTeamMembers(teamId);
        } catch (RuntimeException e) {
            return new ArrayList<>();
        }
    }

    @Override
    public Integer updateTeamMemeberNum(Integer teamId) {
        try {
            teamDao.updateTeamMemberNum(teamId);
            return ResultTypeEnum.SUCCESS.getValue();
        } catch (RuntimeException e) {
            return ResultTypeEnum.FAILED.getValue();
        }
    }
}
